package com.wei.czz.framework.admin.manager;

import com.wei.czz.common.dto.admin.role.RoleDto;
import com.wei.czz.common.enums.CommonEnum;
import com.wei.czz.common.enums.ResultEnum;
import com.wei.czz.common.enums.rabbitMQ.MqEnum;
import com.wei.czz.common.exception.CzzException;
import com.wei.czz.common.po.UserPo;
import com.wei.czz.common.tool.PageDto;
import com.wei.czz.common.utils.CopyUtils;
import com.wei.czz.common.utils.SecurityUtils;
import com.wei.czz.common.vo.admin.role.BindRoleVo;
import com.wei.czz.common.vo.admin.roleGroup.RoleGroupFormVo;
import com.wei.czz.framework.admin.entity.RoleEntity;
import com.wei.czz.framework.admin.entity.RoleGroupEntity;
import com.wei.czz.framework.admin.service.RoleGroupService;
import com.wei.czz.framework.admin.service.RoleService;
import com.wei.czz.framework.common.helper.RabbitHelper;
import com.wei.czz.framework.rabbitMQ.message.roleSpace.RoleSpaceRoleUpdateMessage;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Function;

/**
 * Created by IntelliJ IDEA.
 *
 * @author wyw
 * date: 2024-10-30 16:51:38
 * className: RoleGroupManager
 * version: 1.0
 * description:
 */
@Component
@AllArgsConstructor
public class RoleGroupManager {

    private static final Logger log = LoggerFactory.getLogger(RoleGroupManager.class);

    private final RoleGroupService roleGroupService;

    private final RoleService roleService;

    private final RabbitHelper rabbitHelper;

    public void bindRole(BindRoleVo bindRoleVo) {
        // 获取操作用户
        UserPo userPo = SecurityUtils.getUser();
        Date date = new Date();

        /*
            获取角色授权组已关联角色列表
         */
        List<RoleGroupEntity> roleGroupList = roleGroupService.findList(
                Collections.singletonList(bindRoleVo.getMasterId()), null, null
        );
        Map<Long, RoleGroupEntity> roleGroupMap = new HashMap<>();
        List<RoleGroupEntity> deletedList = new ArrayList<>();
        for (RoleGroupEntity roleGroup : roleGroupList) {
            if (CommonEnum.ZERO.getValue().equals(roleGroup.getDeleteStatus())) {
                roleGroupMap.put(roleGroup.getRoleId(), roleGroup);
            } else {
                deletedList.add(roleGroup);
            }
        }
        log.info("已关联数量：{}", roleGroupMap.size());
        log.info("已删除数量：{}", deletedList.size());
        Iterator<RoleGroupEntity> deletedIterator = deletedList.iterator();

        List<RoleGroupEntity> saveList = new ArrayList<>();
        List<RoleGroupEntity> updateList = new ArrayList<>();

        for (Long roleId : bindRoleVo.getRoleIdList()) {
            RoleGroupEntity roleGroup = roleGroupMap.remove(roleId);
            if (Objects.nonNull(roleGroup)) {
                // 已关联，过滤
                continue;
            }
            // 新关联，添加数据
            if (deletedIterator.hasNext()) {
                roleGroup = deletedIterator.next();

                RoleGroupEntity updateRoleGroup = new RoleGroupEntity();
                updateRoleGroup.setId(roleGroup.getId())
                        .setRoleId(roleId)
                        .setDeleteStatus(CommonEnum.ZERO.getValue())
                        .setUpdateTime(date)
                        .setUpdateUser(userPo.getUsername())
                        .setUpdateUserId(userPo.getUserId());
                updateList.add(updateRoleGroup);
            }
            if (Objects.isNull(roleGroup)) {
                roleGroup = new RoleGroupEntity();
                roleGroup.setSpaceId(bindRoleVo.getMasterId())
                        .setRoleId(roleId)
                        .setDeleteStatus(CommonEnum.ZERO.getValue())
                        .setUpdateTime(date)
                        .setUpdateUser(StringUtils.EMPTY)
                        .setUpdateUserId(CommonEnum.ZERO.getLongValue())
                        .setCreateTime(date)
                        .setCreateUser(userPo.getUsername())
                        .setCreateUserId(userPo.getUserId());
                saveList.add(roleGroup);
            }
        }
        if (saveList.isEmpty() && updateList.isEmpty()) {
            log.info("角色授权组没有新关联的角色");
            throw new CzzException(ResultEnum.REQUEST_FAIL.getCode(), "您选择的角色已关联，请确认后重新操作");
        }

        /*
            保存
         */
        if (!saveList.isEmpty()) {
            roleGroupService.batchSave(saveList);
        }

        /*
            修改
         */
        if (!updateList.isEmpty()) {
            roleGroupService.batchUpdate(updateList);
        }

        if (!saveList.isEmpty() || !updateList.isEmpty()) {
            RoleSpaceRoleUpdateMessage roleSpaceRoleUpdateMessage = CopyUtils.map(bindRoleVo,
                    RoleSpaceRoleUpdateMessage.class);
            roleSpaceRoleUpdateMessage.setOptType(CommonEnum.ZERO.getValue());
            // 发送MQ消息
            rabbitHelper.send(MqEnum.ROLE_SPACE_ROLE, roleSpaceRoleUpdateMessage);
        }
    }

    public PageDto<RoleDto> getPageList(RoleGroupFormVo roleGroupFormVo) {

        /*
            分页获取角色列表
         */
        PageDto<RoleEntity> pageDto = roleService.getRoleSpacePageList(roleGroupFormVo);
        if (pageDto.isEmpty()) {
            log.info("分页获取角色授权组关联角色为空");
            return pageDto.rebuild();
        }
        List<RoleEntity> roleList = pageDto.getList();

        // 列表映射
        BiConsumer<RoleEntity, RoleDto> biConsumer = (role, roleDto) -> {
            roleDto.setStatusName(CommonEnum.getStatusName(role.getStatus()));
        };
        List<RoleDto> roleDtoList = CopyUtils.mapList(roleList, RoleDto.class, biConsumer);
        // 数据封装
        return pageDto.rebuild(roleDtoList);
    }

    public void unbindRole(BindRoleVo bindRoleVo) {
        // 获取操作用户
        UserPo userPo = SecurityUtils.getUser();
        Date date = new Date();

        /*
            获取角色授权组已关联角色列表
         */
        List<RoleGroupEntity> roleGroupList = roleGroupService.findList(
                Collections.singletonList(bindRoleVo.getMasterId()), bindRoleVo.getRoleIdList(),
                CommonEnum.ZERO.getValue()
        );
        if (roleGroupList.isEmpty()) {
            log.info("获取角色授权组已关联角色结果为空");
            throw new CzzException(ResultEnum.REFRESH.getCode(), "选中角色已解除绑定，请确认后重新操作");
        }

        Function<RoleGroupEntity, RoleGroupEntity> function = roleGroup -> {
            RoleGroupEntity updateRoleGroup = new RoleGroupEntity();
            updateRoleGroup.setId(roleGroup.getId())
                    .setDeleteStatus(CommonEnum.ONE.getValue())
                    .setUpdateTime(date)
                    .setUpdateUser(userPo.getUsername())
                    .setUpdateUserId(userPo.getUserId());
            return updateRoleGroup;
        };
        List<RoleGroupEntity> updateList = CopyUtils.mapList(roleGroupList, function);

        /*
            修改
         */
        roleGroupService.batchUpdate(updateList);

        RoleSpaceRoleUpdateMessage roleSpaceRoleUpdateMessage = CopyUtils.map(bindRoleVo,
                RoleSpaceRoleUpdateMessage.class);
        roleSpaceRoleUpdateMessage.setOptType(CommonEnum.ONE.getValue());
        // 发送MQ消息
        rabbitHelper.send(MqEnum.ROLE_SPACE_ROLE, roleSpaceRoleUpdateMessage);

    }
}
